#include "scanner.h"
#include "globals.h"

int printScanner = 0;
int printParser = 0;
int printVmTrace = 0;

// to build, just run "make"
// then ./parser input.txt output.txt

int main(int argc, const char **argv)
{
  // args in order:
  // 1: PL0 code input filename
  // 2: output filename
  // 3: Runtime Flags (Either -l, -a, -v)
  // 4: Runtime Flags (Either -l, -a, -v)
  // 5: Runtime Flags (Either -l, -a, -v)

  /* Flag definitions

    -l : print the list of lexemes/tokens (scanner output) to the screen
    -a : print the generated assembly code (parser/codegen output) to the screen
    -v : print virtual machine execution trace (virtual machine output) to the screen
  */

  //printf("Number of Arguments (argc): %d \n", argc);
  //printf("Real number of Arguments (argc-1) %d\n", argc-1);

  char inputFileName[MAX_PROGRAM_LENGTH], outputFileName[MAX_PROGRAM_LENGTH]/*, vmInputFilename[MAX_PROGRAM_LENGTH]*/;
  strcpy(inputFileName, argv[1]);
  FILE* inPtr = fopen(inputFileName, "r");
  strcpy(outputFileName, argv[2]);
  FILE* outPtr = fopen(outputFileName, "w");

  int i;
  for(i = 3; i < argc; i++) // "./parser" is also an arg! have to start at 4
  {
    //printf("%s\n", argv[i]);
    if(strcmp("-l", argv[i]) == 0)
    {
      //printf("-l found!\n");
      printScanner = 1;
    }
    else if(strcmp("-a", argv[i]) == 0)
    {
      //printf("-a found!\n");
      printParser = 1;
    }
    else if(strcmp("-v", argv[i]) == 0)
    {
      //printf("-v found!\n");
      printVmTrace = 1;
    }
    else
    {
      printf("Invalid directive found!\n");
    }
  }

  if(inPtr == NULL)
  {
    printf("File not found: %s", inputFileName);
    return 0;
  }
  if(outPtr == NULL)
  {
    printf("File not found: %s", outputFileName);
    return 0;
  }

  // scan in PL0 code, get lexeme list
  char lexList[MAX_PROGRAM_LENGTH];
  scan_file(inPtr, outPtr, lexList, printScanner);
  //printf("SUP WORLD %s\n", lexList);

  // parse lexeme list (validate code, get symbol table)
  // generate assembly for vm
  instruction assemblyCode[MAX_CODE_LENGTH];
  int codeLength = parseLexemeList(outPtr, lexList, assemblyCode, printParser);

  fprintf(outPtr, "No errors, program is syntactically correct\n\n");
  if(printParser == 1) printf("No errors, program is syntactically correct\n\n");


  // run assembly on vm, print output
  runVM(outPtr, assemblyCode, codeLength, printVmTrace, printParser);

  fclose(inPtr);
  fclose(outPtr);
  //fclose(vmInputPtr);

  return 0;
}
